package com.symaster.common.test.mousepractise;

import com.symaster.common.geom.entity.LineSegment;
import com.symaster.common.geom.entity.Point;
import com.symaster.common.geom.entity.Vector;
import com.symaster.common.geom.util.PointUtil;
import com.symaster.common.image.util.ImageUtil;
import com.symaster.common.swing.FpsManager;
import com.symaster.common.swing.util.SwingUtil;
import com.symaster.common.thread.WatchThread;

import javax.swing.*;
import java.awt.*;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author yinmiao
 * @version 2023/11/29
 */
public class App1 {

    public static Float time() {
        return System.nanoTime() / 1000000.0f;
    }

    public static void main(String[] args) throws InterruptedException {
        ImageUtil.setupCvCore();

        Canvas canvas = new Canvas();
        // canvas.setBackground(new Color(0, 0, 0, 0));

        JFrame jFrame = new JFrame("App1");
        jFrame.setContentPane(canvas);
        jFrame.setPreferredSize(new Dimension(1920, 1080));
        jFrame.setUndecorated(true);
        jFrame.setBackground(new Color(0, 0, 0, 0));
        jFrame.pack();
        jFrame.setVisible(true);
        SwingUtil.toCenter(jFrame);

        TimeUnit.SECONDS.sleep(3);
        canvas.start = true;
        Controller controller = new Controller(canvas);
        controller.start();
    }

    private static class Controller extends WatchThread {
        private static final int sleepTime = 3;
        private final Canvas canvas;
        private final Random random;

        public Controller(Canvas canvas) throws IllegalArgumentException {
            super(sleepTime * 1000);
            this.canvas = canvas;
            this.random = new Random();
        }

        @Override
        protected void execute() throws Throwable {

            float speed = random.nextFloat() * 200 + 100;

            float offset = 25;

            float len = speed * sleepTime;
            final Point point = canvas.point;

            LineSegment lineSegment = new LineSegment(point, new Point(point.x, point.y - len));

            double angle;
            while (true) {
                angle = random.nextDouble() * 360;
                lineSegment.rotate(point, angle);

                Point endPoint = lineSegment.getEndPoint();

                if (endPoint.getX() < offset || endPoint.getX() > canvas.getWidth() - offset) {
                    continue;
                }

                if (endPoint.getY() < offset || endPoint.getY() > canvas.getHeight() - offset) {
                    continue;
                }

                break;
            }

            canvas.speed = speed;
            canvas.startPoint = new Point(canvas.point.x, canvas.point.y);
            canvas.vector = PointUtil.getTranslateVector(lineSegment.getStartPoint(), lineSegment.getEndPoint());
            canvas.startTime = time();
        }
    }

    private static class Canvas extends JComponent {
        private final FpsManager fpsManager = new FpsManager();
        public float speed = 200f;
        public Point point = new Point(200, 200);
        public boolean start = false;
        public Float fractionStartTime;

        public Vector vector;
        public Float startTime;
        public Point startPoint;
        private float fraction = 0f;

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            final int size = 50;

            if (vector != null && startTime != null && startPoint != null) {
                float len = (time() - startTime) * (speed / 1000);

                double scale = PointUtil.getScale(vector.length(), len);

                double x = vector.getX() * scale + startPoint.getX();
                double y = vector.getY() * scale + startPoint.getY();
                point.setX(x);
                point.setY(y);
            }

            if (point != null) {

                GraphicsDevice device = MouseInfo.getPointerInfo().getDevice();


                boolean flag = false;
                java.awt.Point mousePoint = MouseInfo.getPointerInfo().getLocation();
                if (mousePoint != null) {
                    Vector translateVector = PointUtil.getTranslateVector(mousePoint.x, mousePoint.y, point.x, point.y);
                    if (translateVector.length() < 25) {
                        if (start) {
                            fraction += 0.1f;
                        }
                        flag = true;
                    }
                }

                int x = (int) Math.round(point.getX() - size / 2.0);
                int y = (int) Math.round(point.getY() - size / 2.0);

                Graphics graphics = g.create(x - 1, y - 1, size + 2, size + 2);

                // Scalar scalar;
                // if (flag) {
                //     scalar = new Scalar(255, 255, 0, 120);
                // } else {
                //     scalar = new Scalar(0, 0, 0, 120);
                // }
                // MatOfPoint matOfPoint = PointUtil.polygon2MatOfPoint(new Circle(new Point(point.getX() - x, point.getY() - y), 25.0d).toPolygon());
                // Mat mat = new Mat(size + 2, size + 2, CvType.CV_8UC4, new Scalar(0, 0, 0, 0));
                // Imgproc.fillPoly(mat, Collections.singletonList(matOfPoint), scalar, Imgproc.LINE_8, Imgproc.CC_STAT_TOP);
                // Image image = ImageUtil.matBGRA2ImageRGBA(mat);
                // graphics.drawImage(image, 0, 0, null);
                // graphics.dispose();
                // mat.release();

                try {
                    SwingUtil.antialiasingOn((Graphics2D) graphics);
                    if (flag) {
                        graphics.setColor(new Color(0, 255, 255, 120));
                    } else {
                        graphics.setColor(new Color(0, 0, 0, 120));
                    }

                    graphics.fillOval(1, 1, size, size);
                } finally {
                    graphics.dispose();
                }
            }

            Graphics graphics = g.create(0, getHeight() - 30, 100, 30);
            try {
                SwingUtil.antialiasingOn((Graphics2D) graphics);
                graphics.setColor(new Color(255, 255, 255, 180));
                graphics.fillRect(10, 0, 100, 20);

                graphics.setColor(new Color(0, 0, 0, 255));
                graphics.drawString(String.format("fraction: %s", fraction), 15, 15);
            } finally {
                graphics.dispose();
            }

            fpsManager.paintRunnable(60, this::repaint);
        }
    }
}
